import React, {FC, useEffect, useReducer, useRef} from 'react';
import {Button, Card, FormInstance, Space, Steps} from "antd";
import Step01 from "@/pages/form/step-form/Step01";
import Step03 from "@/pages/form/step-form/Step03";
import Step02 from "@/pages/form/step-form/Step02";
import {StorageUtil} from "pzy-storage-util";

const {Step} = Steps;

interface StepFormDemoProps {
}

const LOCAL_STORAGE_FORM_DATA_KEY = 'stepFormDatas';
const LOCAL_STORAGE_STEP_KEY = 'step_index';
// 总分步数.从0开始,因此这里表示最多3步
const LAST_STEP = 2;
// 第一步索引数
const FIRST_STEP = 0;

const initState = {
    // 记录当前处在分步表单的第几步. 初始值从localStorage中获取,如果没有该值,则填充0(第一步的索引为:0)
    current: StorageUtil.localOpt.getNumberInt(LOCAL_STORAGE_STEP_KEY, 0) as number,
    // 记录分步表单的整体数据. 初始值从localStorage中获取,如果没有该值, 则填充空对象
    stepFormDatas: StorageUtil.localOpt.getJson(LOCAL_STORAGE_FORM_DATA_KEY, {}) as object,
}

const reducer = (state: any, {type, payload}: { type: string, payload?: any }) => {
    switch (type) {
        case 'setNext': {
            const stepFormDatas = {...state.stepFormDatas, ...payload.stepFormDatas};
            const current = ++state.current;
            const newState = {...state, stepFormDatas, current};
            StorageUtil.localOpt.addJson(LOCAL_STORAGE_FORM_DATA_KEY, stepFormDatas)
            StorageUtil.localOpt.addNumber(LOCAL_STORAGE_STEP_KEY, current)
            return newState;
        }
        case 'setPrev': {
            if (state.current === FIRST_STEP) {
                return state;
            }
            const current = --state.current;
            StorageUtil.localOpt.addNumber(LOCAL_STORAGE_STEP_KEY, current)
            return {
                ...state,
                current
            }
        }
        default:
            return state;
    }
}

const StepFormDemo: FC<StepFormDemoProps> = (props) => {
    const {children} = props;

    const [state, dispatch] = useReducer(reducer, initState);
    const {current, stepFormDatas} = state;
    const currentForm = useRef<FormInstance>();

    useEffect(() => {
        console.log('StepFormDemo 组件挂载完毕!');
    }, []);

    console.log('StepFormDemo 组件render!');

    const onPrev = () => {
        dispatch({type: 'setPrev'});
    }
    /**
     * 监听组件挂载完毕, 获取表单实例
     **/
    const onStepFormMounted = (form: FormInstance) => {
        currentForm.current = form;
    }
    /**
     * 监听下一步按钮点击, 执行当前表单的数据验证
     **/
    const onDoNext = () => {
        currentForm.current?.validateFields().then(values => {
            dispatch({type: 'setNext', payload: {stepFormDatas: values}});
        })
    }

    /**
     * 构建分步表单
     *     这里为什么不使用以前的数组方式?<br/>
     *     1、每个分步表单不用再控制显示隐藏,当前界面中始终只存在一个表单,而非以前的所有的表单都在一个界面<br/>
     *     2、进入下一个表单, 上一个表单会执行卸载, 下一个表单会进行挂载, 这样表单数据初始化就能在挂载钩子函数中执行, 不用再在每个表单属性中进行复杂的判断<br/>
     **/
    const buildStepForm = () => {
        switch (current) {
            case 0: {
                return <Step01 onMounted={onStepFormMounted}
                               formData={stepFormDatas}></Step01>
            }
            case 1: {
                return <Step02 onMounted={onStepFormMounted}
                               formData={stepFormDatas}></Step02>
            }
            default: {
                return <Step03 stepFormDatas={stepFormDatas}></Step03>
            }
        }
    }
    return (
        <div>
            <Space direction="vertical" style={{width: '100%'}}>
                <Card><h2>分步表单</h2><small>注意子表单的构建方式,默认数据数据填充方式,以及子组件将表单实例传递给父组件的方式</small></Card>
                <Card>
                    <Steps size="small" current={current}>
                        <Step title="第一步"/>
                        <Step title="第二步"/>
                        <Step title="最后"/>
                    </Steps>
                    {buildStepForm()}
                    <Button onClick={onPrev} disabled={current === FIRST_STEP}>上一步</Button>
                    <Button onClick={onDoNext} disabled={current === LAST_STEP}>下一步</Button>
                </Card>
            </Space>
        </div>
    );
};

export default StepFormDemo;
